<!-- 加班 对话框 -->
<template>
  <el-dialog v-model="dialogVisible" title="加班" width="500" draggable @closed="handlerClosed">
    <el-form ref="formRef" :model="dialogForm" :rules="rules">
      <el-form-item label="日期" size="large"> {{ dialogForm.overtimeDate }} </el-form-item>
      <el-row :gutter="20">
        <el-col :span="12">
          <el-form-item label="姓名" size="large">
            <el-input v-model="dialogForm.userName" readonly size="large" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="部门" size="large">
            <el-input v-model="dialogForm.deptName" readonly size="large" />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="20">
        <el-col :span="24">
          <el-form-item label="项目" size="large" prop="projectId">
            <el-select v-model="dialogForm.projectId" filterable placeholder="选择项目" clearable>
              <el-option v-for="item in projectList" :key="item.id" :label="`${item.code}-${item.cname}`" :value="item.id" />
            </el-select>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="20" v-if="false">
        <el-col :span="12">
          <el-form-item label="工号" size="large">
            <el-input v-model="dialogForm.number" readonly size="large" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="岗位" size="large">
            <el-input v-model="dialogForm.post" readonly size="large" />
          </el-form-item>
        </el-col>
      </el-row>
      <el-form-item label="时段" size="large" prop="overtime">
        <el-time-picker v-model="dialogForm.overtime" :disabled="isComp" is-range range-separator=" - " start-placeholder="开始时间" format="HH:mm" end-placeholder="结束时间" />
      </el-form-item>

      <el-form-item label="工作内容" size="large" prop="reason">
        <el-input v-model="dialogForm.reason" style="width: 100%" :autosize="{ minRows: 4, maxRows: 8 }" type="textarea" placeholder="" />
      </el-form-item>
      <el-form-item label="审批流程" size="large" prop="approvalUsers">
        <OvertimeProcessSteps :user-identity="userIdentity" v-model="dialogForm.approvalUsers" />
      </el-form-item>
    </el-form>
    <template #footer>
      <div class="dialog-footer">
        <el-checkbox v-if="isComp" v-model="flagIsRestDay" label="休息日加班" border class="ipt-chk" @change="handleChangeCbxFlagIsRestDay" />
        <el-button @click="handlerClickBtnCancel">取消</el-button>
        <el-button type="primary" @click="handlerClickBtnSubmit(formRef)">提交</el-button>
      </div>
    </template>
  </el-dialog>
</template>
<script lang="ts" setup>
import { ref, reactive, onMounted } from 'vue'
import { formatDate, getMinutesDifference, addMinutesToDateTime, userRole } from '../../utils'
import { useUsersStore, useProjectssStore } from '../../stores'
import type { FormInstance } from 'element-plus'
import { ElMessage } from 'element-plus'
import OvertimeProcessSteps from '../Overtime/OvertimeProcessSteps.vue'
import api from '../../api'

const userIdentity = ref(-1) // 用户身份

const flagIsRestDay = ref(false)
const emits = defineEmits(['submitSuccessed'])
const dialogVisible = ref(false)
const formRef = ref<FormInstance>()
const date = new Date()
const isComp = ref(false)
const projectList = ref<Array<{ id: number; code: string; cname: string }>>(useProjectssStore().getAllState() as any)
// const overtime = ref<[Date | any, Date | any]>([null, null])
const dialogForm = reactive({
  id: null,
  userId: -1,
  userName: '',
  userNick: '',
  number: '',
  deptId: '',
  deptName: '',
  post: '',
  overtimeDate: formatDate(date, 'yyyy-MM-dd'),
  reason: '',
  durationTime: 0,
  projectId: null,
  overtime: ref<[Date | null, Date | null]>([null, null]),
  approvalUsers: [] as any[],
})
const defaultObj = ref<any>({})
const validateOvertime = (rule: any, value: any, callback: any) => {
  if (value === null || value === undefined) {
    return callback(new Error('请选择加班时间'))
  }
  if (!rule) {
    return callback(new Error('请选择加班时间'))
  }
  if (value[0] && value[1]) {
    callback()
  } else {
    callback(new Error('请选择加班时间'))
  }
}

const rules = reactive({
  overtime: [{ required: true, validator: validateOvertime, trigger: ['change', 'blur'] }],
  reason: [{ required: true, message: '请输入工作内容', trigger: ['change', 'blur'] }],
  projectId: [{ required: true, message: '请选择项目', trigger: ['change', 'blur'] }],
  approvalUsers: [
    {
      required: true,
      validator: (_: any, value: any[], callback: Function) => {
        if (value.length === 0) {
          callback(new Error('请选择审批流程'))
        } else if (value.some((item) => item === null)) {
          callback(new Error('审批流程中不能包含空值'))
        } else {
          callback()
        }
      },
      trigger: ['change', 'blur'],
    },
  ],
})

/**
 * 处理复选框是否为休息日变更事件
 *
 * @param val 是否为休息日
 */
const handleChangeCbxFlagIsRestDay = (val: boolean) => {
  const tempObject = defaultObj.value
  const start = new Date(tempObject.date)
  const end = new Date(tempObject.date)
  const { mornin, evening } = tempObject.clockinInfo
  const [hour1, minute1] = mornin.split(':').map(Number)
  const [hour2, minute2] = evening.split(':').map(Number)
  if (val) {
    start.setHours(hour1, minute1, 0, 0)
    end.setHours(hour2, minute2, 0, 0)
  } else {
    const { city } = useUsersStore().getAllState() as any
    if (city == '北京') {
      // 北京 18:00 下班时间
      start.setHours(18, 0, 0, 0)
    } else {
      start.setHours(17, 30, 0, 0)
    }
    end.setHours(hour2, minute2, 0, 0)
  }
  dialogForm.overtime = [start, end]

  if (end.getTime() < start.getTime()) {
    dialogForm.overtime = [null, null]
  }

  // console.log('start', start, 'end', end)

  // console.log('dialogForm.overtime', dialogForm.overtime)
}

const openDialog = async (objectValue: { date: Date; isComp: boolean; clockinInfo: any }) => {
  console.log('openDialog', objectValue)
  dialogForm.approvalUsers = []
  isComp.value = objectValue.isComp || false
  flagIsRestDay.value = false
  const currentUser = useUsersStore().getAllState()
  if (currentUser) {
    dialogForm.userId = currentUser.userId || -1
    dialogForm.deptId = currentUser.deptId || ''
    dialogForm.deptName = currentUser.deptName || ''
    dialogForm.userName = currentUser.username || ''
    dialogForm.userNick = currentUser.nickName || ''
    dialogForm.deptName = currentUser.deptName || ''
  }
  dialogForm.overtimeDate = formatDate(objectValue.date, 'yyyy-MM-dd')
  dialogForm.reason = ''
  defaultObj.value = objectValue
  dialogVisible.value = true
  dialogForm.projectId = null
  dialogForm.overtime = [null, null]
  if (isComp.value) {
    handleChangeCbxFlagIsRestDay(false)
  }

  // 确认用户身份信息
  const { city, roles, deptId } = useUsersStore().user as any

  userIdentity.value = userRole(city, roles, deptId)
}

/**
 * 处理表单提交按钮点击事件
 *
 * @param formEl 表单实例
 */
const handlerClickBtnSubmit = async (formEl: FormInstance | undefined) => {
  // 如果没有传入表单实例，直接返回
  if (!formEl) return
  // 验证表单
  await formEl.validate(async (valid: any) => {
    // 如果表单验证通过
    if (valid) {
      // dialogForm.durationTime = getTimePercentage(formatDate(end, 'H:mm'), formatDate(start, 'H:mm'))

      // 初始化开始时间和结束时间为null
      let startTime = null
      let endTime = null

      // 如果第一个加班时间不为空
      if (dialogForm.overtime[0]) {
        // 根据加班日期和开始时间构造Date对象
        const startDate = new Date(dialogForm.overtimeDate + ' ' + formatDate(new Date(dialogForm.overtime[0]), 'HH:mm'))
        // 格式化开始时间
        startTime = formatDate(startDate, 'yyyy-MM-dd HH:mm')
      }
      // 如果第二个加班时间不为空
      if (dialogForm.overtime[1]) {
        // 根据加班日期和结束时间构造Date对象
        const endDate = new Date(dialogForm.overtimeDate + ' ' + formatDate(new Date(dialogForm.overtime[1]), 'HH:mm'))
        // 如果结束时间是当天的23:59，则设置为次日的00:00
        if (endDate.getHours() === 23 && endDate.getMinutes() === 59) {
          endDate.setDate(endDate.getDate() + 1)
          endDate.setHours(0, 0, 0, 0)
        }
        // endTime = formatDate(endDate, 'yyyy-MM-dd HH:mm')
      }
      // 初始化秒数为0
      let second = 0
      // 从用户状态存储中获取城市信息
      const { city } = useUsersStore().getAllState() as any
      // 如果两个加班时间都不为空
      if (dialogForm.overtime[0] && dialogForm.overtime[1]) {
        // 计算两个加班时间的分钟差
        second = getMinutesDifference(new Date(dialogForm.overtime[0]), new Date(dialogForm.overtime[1]))
        // 根据城市设置分钟差的处理规则
        if (city == '长春') {
          // 长春 半小时
          // 如果分钟差小于30分钟，则设置为0
          if (second < 30) {
            second = 0 // 小于30分钟，直接设置为0
          }
          // second = Math.floor(second / 30) * 30 // 向上取整到最近的 30 分钟
        } else {
          // 北京 1 小时
          // 向上取整到最近的60分钟
          second = Math.floor(second / 60) * 60 // 向上取整到最近的 60 分钟
        }
        // 根据开始时间和计算出的分钟差计算结束时间
        endTime = addMinutesToDateTime(new Date(dialogForm.overtime[0]), second)
      }

      // 构造请求参数
      const params = {
        ...dialogForm,
        startTime,
        endTime,
        second,
      }

      const leaveUser = {
        userId: dialogForm.userId,
        userName: dialogForm.userName,
        userNick: dialogForm.userNick,
      }
      const removeRes = await api.Overtime.removeOvertime({ userId: leaveUser.userId, userName: leaveUser.userName })

      if (removeRes.code !== 200) {
        ElMessage.error(removeRes.msg)
        return
      }
      const addProcessAll: any[] = []
      let order = 0
      dialogForm.approvalUsers.forEach((item: any) => {
        // console.log('item', item)
        order += 1
        const processUser = {
          processUserId: item.userId,
          processUserName: item.userName,
          processUserNick: item.nickName,
          processOrder: order,
        }
        addProcessAll.push(api.Overtime.addOvertimeProcess(leaveUser, processUser))
      })
      const promisRes = await Promise.all(addProcessAll)

      const allSuccess = promisRes.every((res) => res.code === 200)

      if (!allSuccess) {
        ElMessage.error('添加审批流程失败')
        return
      }
      // return
      // 发送HTTP请求
      const code = await api.Overtime.addOvertime(params)

      // 如果请求成功
      if (code === 200) {
        // 关闭对话框
        dialogVisible.value = false
        // 显示成功消息
        ElMessage({
          message: '提交加班成功！',
          grouping: true,
          type: 'success',
        })
        // 触发提交成功事件
        emits('submitSuccessed')
      } else {
        // 显示失败消息
        ElMessage({
          message: '提交加班失败！',
          grouping: true,
          type: 'error',
        })
      }
    }
  })
}

const handlerClosed = () => {
  handlerClickBtnCancel()
}

const formReset = () => {
  // const objectValue = defaultObj.value
  const currentUser = useUsersStore().getAllState()
  if (currentUser) {
    dialogForm.userId = currentUser.userId || -1
    dialogForm.deptId = currentUser.deptId || ''
    dialogForm.deptName = currentUser.deptName || ''
    dialogForm.userName = currentUser.username || ''
    dialogForm.userNick = currentUser.nickName || ''
    dialogForm.deptName = currentUser.deptName || ''
  }
  dialogForm.reason = ''
  dialogForm.projectId = null
  dialogForm.overtime = [null, null]
  dialogForm.approvalUsers = []
  // clockinform.clockinCategory = objectValue.defaultClockinCategory
  // clockinform.clockinDate = formatDate(objectValue.date, 'yyyy-MM-dd')

  if (isComp.value) {
    // clockinform.clockinTime = new Date(clockinform.clockinDate + ' ' + formatDate(new Date(), 'HH:mm:ss'))
  }
}
const handlerClickBtnCancel = () => {
  formReset()
  dialogVisible.value = false
  if (!formRef.value) return
  formRef.value.resetFields()
}
onMounted(() => {})

defineExpose({
  openDialog,
})
</script>
<style lang="scss" scoped>
.dialog-footer {
  display: flex;
  justify-content: flex-end;
  .ipt-chk {
    margin-right: 14px;
  }
}
</style>
